package com.puntodonna.fogliocassa.client.app.place.fogliocassa;

import java.util.Collection;
import java.util.Date;

import com.google.gwt.core.shared.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.inject.Inject;
import com.gwtplatform.dispatch.shared.DispatchAsync;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.NameToken;
import com.gwtplatform.mvp.client.annotations.ProxyCodeSplit;
import com.gwtplatform.mvp.client.proxy.NotifyingAsyncCallback;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.gwtplatform.mvp.client.proxy.RevealContentEvent;
import com.puntodonna.fogliocassa.client.action.PersistanceAction;
import com.puntodonna.fogliocassa.client.action.PersistanceActionResult;
import com.puntodonna.fogliocassa.client.app.place.login.LoginPresenter;
import com.puntodonna.fogliocassa.client.app.presenter.main.MainPresenter;
import com.puntodonna.fogliocassa.client.place.NameTokens;
import com.puntodonna.fogliocassa.client.resources.FoglioCassaResources;
import com.puntodonna.fogliocassa.client.widget.FogliCassaDataTable;
import com.puntodonna.fogliocassa.client.widget.FoglioCassaInputDialogBox;
import com.puntodonna.fogliocassa.client.widget.MovimentiDataTable;
import com.puntodonna.fogliocassa.client.widget.Movimento;
import com.puntodonna.fogliocassa.shared.FoglioCassaObj;
import com.puntodonna.fogliocassa.shared.MovimentoObj;
import com.puntodonna.fogliocassa.shared.UserObj;

public class FoglioCassaPresenter extends Presenter<FoglioCassaPresenter.MyView, FoglioCassaPresenter.MyProxy> {

	public interface MyView extends View {
		public DockLayoutPanel getFogliCassaArea();

		public DockLayoutPanel getMovimentiArea();

		public FogliCassaDataTable getFogliCassaDataTable();

		public MovimentiDataTable getMovimentiDataTable();

		public Button getOpenBtn();

		public Button getCancelBtn();

		public Button getCloseBtn();

		public Movimento getMovimentoWidget();
	}

	@Inject
	protected LoginPresenter loginPresenter;

	@Inject
	protected FoglioCassaResources resources;

	@Inject
	protected DispatchAsync dispatchAsync;

	@ProxyCodeSplit
	@NameToken(NameTokens.fogliocassa)
	public interface MyProxy extends ProxyPlace<FoglioCassaPresenter> {
	}

	@Inject
	public FoglioCassaPresenter(final EventBus eventBus, final MyView view, final MyProxy proxy) {
		super(eventBus, view, proxy);

	}

	@Override
	protected void revealInParent() {
		RevealContentEvent.fire(this, MainPresenter.TYPE_WIDGET_AREA, this);
	}

	@Override
	protected void onBind() {
		super.onBind();
		
	}
	
	@Override
	protected void onReset() {
		super.onReset();
		setupFogliCassa();
		setupMovimenti();
	}

	@Override
	protected void onHide() {
		super.onHide();
	}

	protected FoglioCassaPresenter getThisPresenter() {
		return this;
	}

	public LoginPresenter getLoginPresenter() {
		return loginPresenter;
	}

	protected void setupMovimenti() {
		final SingleSelectionModel<MovimentoObj> selectionModel = getView().getMovimentiDataTable().getSingleSelectionModel();

		selectionModel.addSelectionChangeHandler(new Handler() {
			@Override
			public void onSelectionChange(SelectionChangeEvent event) {
				MovimentoObj movimentoObj = selectionModel.getSelectedObject();
				if (selectionModel.isSelected(movimentoObj)) {
					getView().getMovimentoWidget().getImportoTextBox().setText(movimentoObj.getLordo().toString());
					getView().getMovimentoWidget().getIvaTextBox().setText(movimentoObj.getPercIVA().toString());
					int index = movimentoObj.getTipoMovimento();
					getView().getMovimentoWidget().getTipoMovimentoListBox().setSelectedIndex(index == -1 ? 1 : 0);
					getView().getMovimentoWidget().getCausaleTextArea().setText(movimentoObj.getCausale());
					getView().getMovimentoWidget().getDataBox().setValue(movimentoObj.getData());
				}
			}
		});

		setupMovimentoWidgetButtons();
	}

	protected void setupMovimentoWidgetButtons() {
		getView().getMovimentoWidget().getOkBtn().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				FoglioCassaObj foglioCassaObj = getView().getFogliCassaDataTable().getSingleSelectionModel().getSelectedObject();
				if (foglioCassaObj == null) {
					getView().getMovimentoWidget().setMessage("Seleziona un foglio cassa!");
					return;
				}

				if (foglioCassaObj.getDataChiusura() != null) {
					getView().getMovimentoWidget().setMessage("Il foglio cassa e' chiuso!");
					return;
				}

				if (getView().getMovimentoWidget().getDataBox().getValue() == null) {
					getView().getMovimentoWidget().setMessage("data: inserire un valore");
					return;
				}

				Double lordo = getView().getMovimentoWidget().getImportoTextBox().getValue();
				if (lordo == null) {
					getView().getMovimentoWidget().setMessage("importo: inserire un valore");
					return;
				}
				Double percIva = getView().getMovimentoWidget().getIvaTextBox().getValue();
				if (percIva == null) {
					getView().getMovimentoWidget().setMessage("%iva: inserire un valore");
					return;
				}
				String causale = getView().getMovimentoWidget().getCausaleTextArea().getValue();
				if (causale == null || causale.isEmpty()) {
					getView().getMovimentoWidget().setMessage("causale: inserire un valore");
					return;
				}
				int tipoMovimento = getView().getMovimentoWidget().getTipoMovimentoListBox().getSelectedIndex();

				double iva = 1;
				double netto = 0;
				if (percIva.doubleValue() != 0) {
					iva = ((lordo.doubleValue() * percIva.doubleValue()) / 100.00);
					netto = lordo.doubleValue() - iva;
				} else
					netto = lordo.doubleValue();

				if (tipoMovimento == 1 && lordo > 0) {
					netto *= -1;
					lordo *= -1;
				}

				MovimentoObj movimentoObj = getView().getMovimentiDataTable().getSingleSelectionModel().getSelectedObject();
				String actionStr = PersistanceAction.ACTION_MV_UPDATE;
				if (movimentoObj == null) {
					movimentoObj = new MovimentoObj();
					actionStr = PersistanceAction.ACTION_MV_SAVE;
				}

				movimentoObj.setData(getView().getMovimentoWidget().getDataBox().getValue());
				movimentoObj.setLordo(lordo);
				movimentoObj.setNetto(netto);
				movimentoObj.setIva(iva);
				movimentoObj.setPercIva(percIva);
				movimentoObj.setCausale(causale);
				movimentoObj.setTipoMovimento(tipoMovimento == 1 ? -1 : 1);

				PersistanceAction action = PersistanceAction.getMovimentoPersistanceAction(actionStr, movimentoObj, foglioCassaObj);
				doAction(action);

			}
		});

		getView().getMovimentoWidget().getClearBtn().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				getView().getMovimentoWidget().reset();
				getView().getMovimentiDataTable().getSingleSelectionModel().clear();
			}
		});

		getView().getMovimentoWidget().getCancelBtn().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				FoglioCassaObj foglioCassaObj = getView().getFogliCassaDataTable().getSingleSelectionModel().getSelectedObject();
				MovimentoObj movimentoObj = getView().getMovimentiDataTable().getSingleSelectionModel().getSelectedObject();
				if (movimentoObj != null) {
					if (Window.confirm("Sei sicuro di voler cancellare il movimento selezionato?")) {
						PersistanceAction action = PersistanceAction.getMovimentoPersistanceAction(PersistanceAction.ACTION_MV_DELETE, movimentoObj, foglioCassaObj);
						doAction(action);
					}
				}
			}
		});
	}

	protected void setupFogliCassa() {
		UserObj userObj = getLoginPresenter().getUserObj();
		
		getView().getFogliCassaDataTable().clear();
		
		PersistanceAction action = PersistanceAction.getAllFoglioCassaPersistanceAction(userObj);
		doAction(action);

		final SingleSelectionModel<FoglioCassaObj> selectionModel = getView().getFogliCassaDataTable().getSingleSelectionModel();

		selectionModel.addSelectionChangeHandler(new Handler() {
			@Override
			public void onSelectionChange(SelectionChangeEvent event) {
				FoglioCassaObj foglioCassaObj = selectionModel.getSelectedObject();
				if (selectionModel.isSelected(foglioCassaObj)) {
					getView().getMovimentiDataTable().clear();
					getView().getMovimentiDataTable().addItems(foglioCassaObj.getMovimenti().values());
					getView().getMovimentoWidget().reset();
					getView().getMovimentiArea().setVisible(true);
					if (foglioCassaObj.getDataChiusura() == null)
						getView().getOpenBtn().setVisible(false);
					else
						getView().getOpenBtn().setVisible(true);
				} else {
					getView().getMovimentiDataTable().clear();
					getView().getMovimentoWidget().reset();
					getView().getMovimentiArea().setVisible(false);
					getView().getOpenBtn().setVisible(true);
				}
			}
		});

		setupFogliCassaButtons();
	}

	protected void setupFogliCassaButtons() {
		final UserObj userObj = getLoginPresenter().getUserObj();
		getView().getOpenBtn().addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				final FoglioCassaInputDialogBox foglioCassaInputDialogBox = new FoglioCassaInputDialogBox(new Date());
				foglioCassaInputDialogBox.setAnimationEnabled(true);
				foglioCassaInputDialogBox.setGlassEnabled(true);
				foglioCassaInputDialogBox.setText("Apertura Foglio Cassa");
				if (getView().getFogliCassaDataTable().getSingleSelectionModel().getSelectedObject() != null)
					foglioCassaInputDialogBox.getNomeTextBox().setText(getView().getFogliCassaDataTable().getSingleSelectionModel().getSelectedObject().getNome());
				foglioCassaInputDialogBox.getOkBtn().addClickHandler(new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						final SingleSelectionModel<FoglioCassaObj> selectionModel = getView().getFogliCassaDataTable().getSingleSelectionModel();
						FoglioCassaObj foglioCassaObj = selectionModel.getSelectedObject();
						String actionStr = null;
						if (foglioCassaObj == null) {
							foglioCassaObj = new FoglioCassaObj();
							actionStr = PersistanceAction.ACTION_FC_SAVE;
						} else if (foglioCassaObj.getDataChiusura() != null) {
							foglioCassaObj.setDataChiusura(null);
							actionStr = PersistanceAction.ACTION_FC_UPDATE;
						}
						foglioCassaObj.setDataApertura(foglioCassaInputDialogBox.getDateBox().getValue());
						foglioCassaObj.setNome(foglioCassaInputDialogBox.getNomeTextBox().getValue());

						if (actionStr != null) {
							PersistanceAction action = PersistanceAction.getFoglioCassaPersistanceAction(actionStr, userObj, foglioCassaObj);
							doAction(action);
						}

						foglioCassaInputDialogBox.hide();
					}
				});

				foglioCassaInputDialogBox.getCancelBtn().addClickHandler(new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						foglioCassaInputDialogBox.hide();
					}

				});

				foglioCassaInputDialogBox.center();
			}
		});

		getView().getCancelBtn().addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				final SingleSelectionModel<FoglioCassaObj> selectionModel = getView().getFogliCassaDataTable().getSingleSelectionModel();
				final FoglioCassaObj foglioCassaObj = selectionModel.getSelectedObject();
				if (foglioCassaObj != null) {
					if (Window.confirm("Sei sicuro di voler cancellare il foglio cassa " + foglioCassaObj.getNome() + "?")) {
						PersistanceAction action = PersistanceAction.getFoglioCassaPersistanceAction(PersistanceAction.ACTION_FC_DELETE, userObj, foglioCassaObj);
						doAction(action);
					}
				}
			}
		});

		getView().getCloseBtn().addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				final SingleSelectionModel<FoglioCassaObj> selectionModel = getView().getFogliCassaDataTable().getSingleSelectionModel();
				final FoglioCassaObj foglioCassaObj = selectionModel.getSelectedObject();
				if (foglioCassaObj != null) {
					final FoglioCassaInputDialogBox foglioCassaInputDialogBox = new FoglioCassaInputDialogBox(new Date());
					foglioCassaInputDialogBox.setAnimationEnabled(true);
					foglioCassaInputDialogBox.setGlassEnabled(true);
					foglioCassaInputDialogBox.setText("Chiusura Foglio Cassa");
					foglioCassaInputDialogBox.getNomeTextBox().setText(foglioCassaObj.getNome());
					foglioCassaInputDialogBox.getNomeTextBox().setText(foglioCassaObj.getNome());
					foglioCassaInputDialogBox.getNomeTextBox().setEnabled(false);

					foglioCassaInputDialogBox.getOkBtn().addClickHandler(new ClickHandler() {

						@Override
						public void onClick(ClickEvent event) {
							foglioCassaObj.setDataChiusura(foglioCassaInputDialogBox.getDateBox().getValue());
							selectionModel.clear();
							PersistanceAction action = PersistanceAction.getFoglioCassaPersistanceAction(PersistanceAction.ACTION_FC_UPDATE, userObj, foglioCassaObj);
							doAction(action);
							foglioCassaInputDialogBox.hide();
						}
					});

					foglioCassaInputDialogBox.getCancelBtn().addClickHandler(new ClickHandler() {

						@Override
						public void onClick(ClickEvent event) {
							foglioCassaInputDialogBox.hide();
						}

					});

					foglioCassaInputDialogBox.center();

				}
			}
		});

	}

	protected NotifyingAsyncCallback<PersistanceActionResult> getAsyncCallback() {
		return new NotifyingAsyncCallback<PersistanceActionResult>(getProxy().getEventBus()) {

			@Override
			protected void success(PersistanceActionResult result) {
				try {
					String action = result.getAction();
					if (action.equals(PersistanceAction.ACTION_FC_GETALL)) {
						Collection<FoglioCassaObj> foglioCassaObjs = result.getFogliCassaCollection();
						getView().getFogliCassaDataTable().addItems(foglioCassaObjs);
					} else if (action.equals(PersistanceAction.ACTION_FC_SAVE)) {
						FoglioCassaObj foglioCassaObj = result.getFoglioCassaObj();
						getView().getFogliCassaDataTable().addItem(foglioCassaObj);
						getView().getFogliCassaDataTable().getSingleSelectionModel().setSelected(foglioCassaObj, true);
					} else if (action.equals(PersistanceAction.ACTION_FC_UPDATE)) {
						FoglioCassaObj foglioCassaObj = result.getFoglioCassaObj();
						getView().getFogliCassaDataTable().modifyItem(foglioCassaObj);
						getView().getFogliCassaDataTable().getSingleSelectionModel().setSelected(foglioCassaObj, false);
						getView().getFogliCassaDataTable().getSingleSelectionModel().setSelected(foglioCassaObj, true);
					} else if (action.equals(PersistanceAction.ACTION_FC_DELETE)) {
						FoglioCassaObj foglioCassaObj = result.getFoglioCassaObj();
						getView().getFogliCassaDataTable().removeItem(foglioCassaObj);
						getView().getFogliCassaDataTable().getSingleSelectionModel().clear();
					} else if (action.equals(PersistanceAction.ACTION_MV_SAVE)) {
						MovimentoObj movimentoObj = result.getMovimentoObj();
						getView().getMovimentiDataTable().addItem(movimentoObj);
						getView().getMovimentoWidget().reset();
						FoglioCassaObj foglioCassaObj = getView().getFogliCassaDataTable().getSingleSelectionModel().getSelectedObject();
						foglioCassaObj.add(movimentoObj);
						getView().getFogliCassaDataTable().refresh();
					} else if (action.equals(PersistanceAction.ACTION_MV_UPDATE)) {
						MovimentoObj movimentoObj = result.getMovimentoObj();
						getView().getMovimentiDataTable().modifyItem(movimentoObj);
						getView().getMovimentiDataTable().getSingleSelectionModel().clear();
						getView().getMovimentoWidget().reset();
						FoglioCassaObj foglioCassaObj = getView().getFogliCassaDataTable().getSingleSelectionModel().getSelectedObject();
						foglioCassaObj.add(movimentoObj);
						getView().getFogliCassaDataTable().refresh();
					} else if (action.equals(PersistanceAction.ACTION_MV_DELETE)) {
						MovimentoObj movimentoObj = result.getMovimentoObj();
						getView().getMovimentiDataTable().removeItem(movimentoObj);
						getView().getMovimentiDataTable().getSingleSelectionModel().clear();
						getView().getMovimentoWidget().reset();
						FoglioCassaObj foglioCassaObj = getView().getFogliCassaDataTable().getSingleSelectionModel().getSelectedObject();
						foglioCassaObj.getMovimenti().remove(movimentoObj.getId());
						getView().getFogliCassaDataTable().refresh();
					} else {
						GWT.log("PersistanceAction-unknown action: " + action);
						Window.alert("PersistanceAction-unknown action: " + action);
					}
				} catch (Exception e) {
					GWT.log("PersistanceAction failed (client side)!", e);
					Window.alert("PersistanceAction failed (client side)!\r\n" + e);
				}
			}

			@Override
			protected void failure(Throwable caught) {
				GWT.log("PersistanceAction failed (server side)!", caught);
				Window.alert("PersistanceAction failed (server side)!\r\n" + caught);
			}

		};
	}

	protected void doAction(PersistanceAction action) {
		NotifyingAsyncCallback<PersistanceActionResult> callback = getAsyncCallback();
		callback.prepare();
		getDispatchAsync().execute(action, callback);
		callback.checkLoading();
	}

	@Override
	protected void onReveal() {
		super.onReveal();
	}

	@Override
	protected void onUnbind() {
		super.onUnbind();
	}

	public DispatchAsync getDispatchAsync() {
		return dispatchAsync;
	}

	public FoglioCassaResources getResources() {
		return resources;
	}

}
